One of the commonly-used data structure in Java language is “map,” which is a data store that organizes data as (key, value) pairs. The key in a (key, value) pair uniquely identifies the corresponding value. An application programming interface (API) to the map supports operations which allow values to be added to (via a put operation), retrieved from (via a get operation), or removed from (via a remove operation) the map. In all of these three cases, a key is presented to the API to identify the corresponding value being added, retrieved or removed.
In some scenarios, the data store can be very large and can be partitioned and/or replicated across many host machines. Thus, any changes to the (key, value) pairs need to be propagated from machine to machine. As an example, Red Hat® Infinispan implements a high-performance cache organized as a map. When an Infinispan client requests a put operation to be performed on a cache value identified by a key, the put operation can potentially replace an existing cache value (i.e., a previous value). Thus, the client can be presented with a choice between a first put operation that returns a previous value (or some clearly identified null value if no entry was present previously), or a second put operation that does not return a previous value. A client that requires a return value may need to wait while the update is propagated to other host machines in order to be sure the correct previous value is returned. By contrast, a client that does not need the return value can proceed without waiting and, therefore, can speed up its operations.
In other scenarios, a client is presented with an API that only implements a put operation that returns a previous value, regardless of whether or not the client needs the previous value. For example, there are two standard APIs defined by the Java language runtime interfaces “Map” and “ConcurrentMap,” both of which support the set of operations: get, put and remove, but the put operation has only the implementation that returns the previous value. This means that a client needs to wait for the result to be computed and returned, even if it ignores the returned result. This unnecessary wait time can significantly slow down the operations of the application code.
The problem of unnecessary wait time may be resolved, in some cases, by re-writing the client application so it is parameterized to accept only an Infinispan cache. In cases where the return value is needed, the client can invoke the put operation that returns a result. In cases where the return value is ignored, the other put operation can be invoked. However, there are legitimate cases where code needs to be able to operate on any map, not just an Infinispan cache. There may also be other reasons why it is not possible to redefine client code, e.g., the client code is proprietary, the client code forms part of the Java runtime, or the client code is frozen due to logistical, commercial or other hurdles.